﻿using System;
using System.Runtime.CompilerServices;
using UnityEngine;
using UnityEngine.Networking;

public class RangeWeapon : Weapon
{
    public float explosionDamage;
    public float explosionRadius;
    public Effect hitEffect;
    public Effect missileEffect;
    public float missileFlySpeed = 10f;
    public float missileGravity;
    public float missileInaccuracy;
    public int missilePiercingCount;
    public Vector3 muzzleDirection = new Vector3(0f, 0f, 1f);
    public Vector3 muzzleOffset = new Vector3(0f, 0.5f, 0.5f);
    public float prepareDuration;
    public float recoil;
    private Coroutine useEffectPrepareCoroutine;
    private Coroutine usePrepareCoroutine;

    public virtual void MissileExplode(Missile missile)
    {
        if (this.explosionRadius > 0f)
        {
            CombatUtility.ApplyExplosionDamageAndImpact(missile.user, this.explosionDamage, missile.transform.position, this.explosionRadius, base.targetLayerMask, base.impact);
            this.SpawnExplosionEffect(missile);
        }
    }

    public virtual void MissileHit(Missile missile, RaycastHit hit)
    {
        this.Hit(missile.user, hit.collider.GetCharacter(), hit.point, -missile.transform.forward);
        this.SpawnHitEffect(missile, hit);
    }

    public override void OnDeserialize(NetworkReader reader, bool initialState)
    {
        base.OnDeserialize(reader, initialState);
    }

    private void OnDrawGizmosSelected()
    {
        DebugDraw.DrawArrow(base.transform.TransformPoint(this.muzzleOffset), base.transform.TransformDirection(this.muzzleDirection), 0.25f, 20f);
    }

    public override bool OnSerialize(NetworkWriter writer, bool forceAll)
    {
        bool flag;
        bool flag2 = base.OnSerialize(writer, forceAll);
        return (flag | flag2);
    }

    protected override void OnUse(Character user)
    {
        <OnUse>c__AnonStorey54 storey = new <OnUse>c__AnonStorey54 {
            user = user,
            <>f__this = this
        };
        base.OnUse(storey.user);
        if (this.usePrepareCoroutine != null)
        {
            base.StopCoroutine(this.usePrepareCoroutine);
        }
        this.usePrepareCoroutine = this.StartWaitForSeconds(this.prepareDuration, new Action(storey.<>m__89));
    }

    public virtual Effect SpawnExplosionEffect(Missile missile)
    {
        return ((this.hitEffect == null) ? null : this.hitEffect.Spawn<Effect>(missile.transform.position, Quaternion.LookRotation(missile.velocity)));
    }

    public virtual Effect SpawnHitEffect(Missile missile, RaycastHit hit)
    {
        return ((this.hitEffect == null) ? null : this.hitEffect.Spawn<Effect>(hit.point, Quaternion.LookRotation(missile.velocity)));
    }

    public virtual void SpawnMissile()
    {
        <SpawnMissile>c__AnonStorey55 storey = new <SpawnMissile>c__AnonStorey55 {
            <>f__this = this
        };
        Vector3 position = base.transform.TransformPoint(this.muzzleOffset);
        Vector3 vector2 = new Vector3(UnityEngine.Random.Range(-this.missileInaccuracy, this.missileInaccuracy), 0f, 0f);
        Vector3 forward = base.transform.TransformDirection(this.muzzleDirection + vector2);
        Quaternion rotation = Quaternion.LookRotation(forward);
        storey.missile = new GameObject(base.name + "_Missile").AddComponent<Missile>();
        storey.missile.user = base.user;
        storey.missile.transform.position = position;
        storey.missile.transform.rotation = rotation;
        storey.missile.startLifetime = base.attackRange / this.missileFlySpeed;
        storey.missile.layerMask = base.targetLayerMask;
        storey.missile.velocity = (Vector3) (forward * this.missileFlySpeed);
        storey.missile.gravity = this.missileGravity;
        storey.missile.piercingCount = this.missilePiercingCount;
        storey.missile.onHit = new Action<RaycastHit>(storey.<>m__8A);
        storey.missile.onDie = new Action(storey.<>m__8B);
        if (this.missileEffect != null)
        {
            this.missileEffect.Spawn<Effect>(position, rotation).transform.parent = storey.missile.transform;
        }
        base.ConsumeUserEnergy();
    }

    public override void SpawnUseEffect()
    {
        if (this.useEffectPrepareCoroutine != null)
        {
            base.StopCoroutine(this.useEffectPrepareCoroutine);
        }
        this.useEffectPrepareCoroutine = this.StartWaitForSeconds(this.prepareDuration, delegate {
            if (base.useEffect != null)
            {
                Vector3 position = base.transform.TransformPoint(this.muzzleOffset);
                Quaternion rotation = Quaternion.LookRotation(base.transform.TransformDirection(this.muzzleDirection));
                base.useEffect.Spawn<Effect>(position, rotation);
            }
        });
    }

    private void UNetVersion()
    {
    }

    public float ammo
    {
        get
        {
            return base.durability;
        }
        set
        {
            base.durability = value;
        }
    }

    public bool isMissilePiercing
    {
        get
        {
            return (this.missilePiercingCount > 0);
        }
    }

    [CompilerGenerated]
    private sealed class <OnUse>c__AnonStorey54
    {
        internal RangeWeapon <>f__this;
        internal Character user;

        internal void <>m__89()
        {
            if ((this.<>f__this.recoil != 0f) && (this.user != null))
            {
                CombatUtility.ApplyImpact(this.user, (Vector3) (-this.<>f__this.transform.TransformDirection(this.<>f__this.muzzleDirection) * this.<>f__this.recoil));
            }
            this.<>f__this.SpawnMissile();
        }
    }

    [CompilerGenerated]
    private sealed class <SpawnMissile>c__AnonStorey55
    {
        internal RangeWeapon <>f__this;
        internal Missile missile;

        internal void <>m__8A(RaycastHit hit)
        {
            this.<>f__this.MissileHit(this.missile, hit);
        }

        internal void <>m__8B()
        {
            this.<>f__this.MissileExplode(this.missile);
        }
    }
}

